package org.gaaidou.ptarmigan.springboot.core.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.gaaidou.ptarmigan.springboot.core.BaseEnum;
import org.gaaidou.ptarmigan.springboot.core.common.DateUtil;
import org.gaaidou.ptarmigan.springboot.core.serialize.json.ObjectMapperFactory;
import org.gaaidou.ptarmigan.springboot.core.serialize.xml.XmlMapperFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.lang.NonNull;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.Date;
import java.util.Set;

@Configuration
@ComponentScan("org.gaaidou.ptarmigan.springboot.core.web")
public class WebConfig {

    @Bean
    public WebHandlerInterceptor webHandlerInterceptor() {
        return new WebHandlerInterceptor();
    }


    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        return ObjectMapperFactory.getInstance();
    }

    @Bean
    public XmlMapper xmlMapper() {
        return XmlMapperFactory.getInstance();
    }

    @Bean
    public GenericConverter baseEnumConverter() {
        return new GenericConverter() {
            @Override
            public Set<ConvertiblePair> getConvertibleTypes() {
                return Collections.singleton(new ConvertiblePair(String.class, BaseEnum.class));
            }

            @Override
            public BaseEnum convert(Object value, @NonNull TypeDescriptor source, @NonNull TypeDescriptor target) {
                if (null != value && BaseEnum.class.isAssignableFrom(target.getObjectType())) {
                    BaseEnum[] enumConstants = (BaseEnum[]) target.getObjectType().getEnumConstants();
                    for (BaseEnum enumConstant : enumConstants) {
                        if (enumConstant.getValue().toString().equals(value.toString())) {
                            return enumConstant;
                        }
                    }
                }
                return null;
            }
        };
    }


    @Bean
    public Converter<String, String> stringToStringConverter() {
        return new Converter<String, String>() {
            @Override
            public String convert(String source) {
                if (StringUtils.hasText(source)) {
                    return source.trim();
                } else {
                    return null;

                }
            }
        };
    }


    @Bean
    public Converter<String, Date> stringToDateConverter() {
        return new Converter<String, Date>() {
            @Override
            public Date convert(String source) {
                if (StringUtils.hasText(source)) {
                    return DateUtil.parse(source);
                } else {
                    return null;
                }
            }
        };
    }
}
